from os.path import realpath
from pathlib import Path
from docutils import nodes
from sphinx.domains import ObjType
from sphinx.domains.std import OptionXRefRole, Cmdoption, StandardDomain
from sphinx.util.nodes import make_id

import sys

sys.path.append(realpath(Path(__file__).parents[1]))
from sievemgr import __author__, __copyright__, __version__

project = 'SieveManager'
release = __version__
copyright = __copyright__
author = __author__

extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.autosectionlabel',
    'sphinx.ext.autosummary',
    'sphinx.ext.intersphinx',
    'sphinx.ext.mathjax',
    'sphinx.ext.napoleon',
    'sphinx.ext.viewcode',
    #'extra.domain'
]

templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

language = 'en'

intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}

autodoc_member_order = 'bysource'
autodoc_preserve_defaults = True

html_title = f'{project} {release}'
html_static_path = ['_static/html/custom.css']
html_theme = 'furo'

# FIXME: Once internal linking words, these should not be needed.
html_theme_options = {
    "light_css_variables": {
        "color-api-name": "black",
        "color-api-pre-name": "black",
    },
    "dark_css_variables": {
        "color-api-name": "white",
        "color-api-pre-name": "white"
    }
}
html_css_files = [
    'custom.css',
]

man_pages = [
    ('sievemgr', 'sievemgr', 'manage Sieve scripts remotely', '', 1),
    ('sieverc', 'sieverc', 'sievemgr configuration file', '', 5)
]


#
# Custom Sphinx roles
#

class Term(Cmdoption):
    def add_target_and_index(self, firstname, sig, signode) -> None:
        for optname in signode.get('allnames', []):
            node_id = make_id(self.env, self.state.document,
                              self.termprefix, optname)
            signode['ids'].append(node_id)
        self.state.document.note_explicit_target(signode)
        domain = self.env.domains['std']
        for option in signode.get('allnames', []):
            entry = '; '.join([self.termdescr, option])
            node = ('pair', entry, signode['ids'][0], '', None)
            self.indexnode['entries'].append(node)

class TermXRef(OptionXRefRole):
    def process_link(self, env, refnode, has_explicit_title, title, target):
        return title, target

class SieveCmd(Term):
    termprefix = 'subcommand'
    termdescr = 'command'

StandardDomain.object_types['subcommand'] = ObjType('command', 'subcommand')
StandardDomain.directives['subcommand'] = SieveCmd
StandardDomain.roles['subcommand'] = TermXRef(lowercase=True, warn_dangling=True)

class ConfVar(Term):
    termprefix = 'confvar'
    termdescr = 'configuration variable'

StandardDomain.object_types['confvar'] = ObjType('configuration variable', 'confvar')
StandardDomain.directives['confvar'] = ConfVar
StandardDomain.roles['confvar'] = TermXRef(lowercase=True, warn_dangling=True)

# FIXME:
# Check https://github.com/sphinx-doc/sphinx/blob/master/sphinx/domains/std.py
# Maybe StandardDomain can be sub-classed
# and we can do our own setup.
# https://opensource.com/article/18/11/building-custom-workflows-sphinx
